home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / interapplication comm / ae interaction sample / reciever.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  14.9 KB  |  425 lines

  1. /*
  2.     File:        reciever.c
  3.  
  4.     Contains:    Sender and Reciever are simple AppleEvent programs that demonstrate     
  5.                 all the permutations of interaction levels for sending    
  6.                 and recieving APpleEvents.
  7.                  Have fun with them.
  8.                  P.S. This also uses PBCatSearch, so I've done the typing for you if you've wanted
  9.                 to use this call but have been confused by the param block    
  10.  
  11.     Written by:     
  12.  
  13.     Copyright:    Copyright © 1984-1999 by Apple Computer, Inc., All Rights Reserved.
  14.  
  15.                 You may incorporate this Apple sample source code into your program(s) without
  16.                 restriction. This Apple sample source code has been provided "AS IS" and the
  17.                 responsibility for its operation is yours. You are not permitted to redistribute
  18.                 this Apple sample source code as "Apple sample source code" after having made
  19.                 changes. If you're going to re-distribute the source, we require that you make
  20.                 it clear in the source that the code was descended from Apple sample source
  21.                 code, but that you've made changes.
  22.  
  23.     Change History (most recent first):
  24.                 7/20/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  25.                 
  26.  
  27. */
  28.     
  29. #include <Types.h>
  30. #include <memory.h>
  31. #include <Packages.h>
  32. #include <Errors.h>
  33. #include <quickdraw.h>
  34. #include <fonts.h>
  35. #include <dialogs.h>
  36. #include <windows.h>
  37. #include <menus.h>
  38. #include <events.h>
  39. #include <OSEvents.h>
  40. #include <Desk.h>
  41. #include <diskinit.h>
  42. #include <OSUtils.h>
  43. #include <resources.h>
  44. #include <toolutils.h>
  45. #include <AppleEvents.h>
  46. #include <EPPC.h>
  47. #include <GestaltEqu.h>
  48. #include <PPCToolbox.h> 
  49. #include <Processes.h>
  50. void DoDiskEvents(long dinfo);                              /* hi word is error code, lo word is drive number */
  51.  
  52. void DrawMain(WindowPtr drawIt);
  53.  
  54. Boolean DoSelected(long val);
  55.  
  56. void InitAEStuff(void);
  57.  
  58. void DoHighLevel(EventRecord *AERecord);
  59. void DoDaCall(MenuHandle themenu, long theit);
  60.      OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  61.  
  62.      OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  63.  
  64.      OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  65.  
  66.      OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  67.  
  68.      OSErr AESimpleHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  69. pascal Boolean idleProc(EventRecord *eventIn, long *sleep, RgnHandle *mouseRgn);
  70. /* interaction menu items */
  71. #define kSelfInteractItem 1
  72. #define kLocalInteractItem 2
  73. #define kAllInteractItem 3
  74. short gInteractArray[4] = 
  75. {
  76.     nil, kAEInteractWithSelf, kAEInteractWithLocal, kAEInteractWithAll
  77. };
  78.  
  79.  
  80. #define kMBarID 128
  81. #define kAppleMenu 128
  82. #define kFileMenu 129
  83. #define kEditMenu 130
  84. #define kToolsMenu 131
  85. #define kResumeMask             1       /* bit of message field for resume vs. suspend */
  86. MenuHandle gAppleMenuHandle, gFileMenuHandle, gEditMenuHandle, gToolMenuHandle;
  87. Handle gMymenu;                                             /* my menu bar handle */
  88.  
  89. AEAddressDesc targetAddress;                                /* address of the person to get the data from */
  90.  
  91.  
  92. #define kSimpleEvent 'SIMP'
  93. #define kSimpleClass 'Simp'
  94. Boolean gQuit, gInBackground;
  95. EventRecord gERecord;
  96. WindowPtr myWindow;
  97. short gInteractNow = kSelfInteractItem;
  98. AEIdleUPP  gAEIdleUPP;
  99.  
  100.  
  101. void main()
  102. {
  103.     WindowPtr twindow;
  104.     MaxApplZone();
  105.     InitGraf((Ptr)&qd.thePort);
  106.     InitFonts();
  107.     InitWindows();
  108.     InitMenus();
  109.     TEInit();
  110.     InitDialogs(nil);
  111.     InitCursor();
  112.     
  113.     InitAEStuff();
  114.     
  115.     gMymenu = GetNewMBar(kMBarID);
  116.     SetMenuBar(gMymenu);
  117.     gAppleMenuHandle = GetMenuHandle(kAppleMenu);
  118.     gFileMenuHandle = GetMenuHandle(kFileMenu);
  119.     gEditMenuHandle = GetMenuHandle(kEditMenu);
  120.     gToolMenuHandle = GetMenuHandle(kToolsMenu);
  121.     
  122.     AppendResMenu(gAppleMenuHandle, 'DRVR');
  123.     DrawMenuBar();
  124.     CheckItem(gToolMenuHandle, gInteractNow, true);
  125.     GetNewWindow(128, nil, (WindowPtr)-1);
  126.     
  127.     do {
  128.         WaitNextEvent(everyEvent, &gERecord, 30, nil);
  129.         switch (gERecord.what) {
  130.             
  131.             case nullEvent:
  132.                 /* no nul processing in this sample */
  133.                 break;
  134.             case updateEvt:
  135.                 DrawMain((WindowPtr)gERecord.message);      /* draw whatever window needs an update */
  136.                 break;
  137.             case mouseDown:
  138.                 /* first see where the hit was */
  139.                 switch (FindWindow(gERecord.where, &twindow)) {
  140.                     
  141.                     case inDesk:                            /* if they hit in desk, then the process manager */
  142.                         break;                              /* will switch us out, we don't need to do anything */
  143.                     case inMenuBar:
  144.                         DoSelected(MenuSelect(gERecord.where));
  145.                         break;
  146.                         
  147.                     case inSysWindow:
  148.                         /* pass to the system */
  149.                         SystemClick(&gERecord, twindow);
  150.                         break;
  151.                     case inContent:
  152.                         break;
  153.                     case inDrag:
  154.                         if (twindow == FrontWindow())
  155.                             DragWindow(twindow, gERecord.where, &qd.screenBits.bounds);
  156.                         break;
  157.                     case inGrow:
  158.                     case inGoAway:
  159.                         /* don't care */
  160.                         break;
  161.                         
  162.                 }
  163.             case mouseUp:
  164.                 /* don't care */
  165.                 break;
  166.                 /* same action for key or auto key */
  167.             case keyDown:
  168.             case autoKey:
  169.                 if (gERecord.modifiers & cmdKey)
  170.                     DoSelected(MenuKey(gERecord.message & charCodeMask));
  171.                 break;
  172.             case keyUp:
  173.                 /* don't care */
  174.                 break;
  175.             case diskEvt:
  176.                 /* I don't do anything special for disk events, this just passes them */
  177.                 /* to a function that checks for an error on the mount */
  178.                 DoDiskEvents(gERecord.message);
  179.                 break;
  180.             case activateEvt:
  181.                 /* Draws on a window activate.  Other activate/deactivate stuff is */
  182.                 /* handled in either the ChangePlane function (for normal shuffling ) */
  183.                 /* or in the suspend/resume handler for layer swaps */
  184.                 if (gERecord.modifiers & activeFlag)
  185.                     DrawMain((WindowPtr)gERecord.message);
  186.                 break;
  187.             case networkEvt:
  188.                 /* don't care */
  189.                 break;
  190.             case driverEvt:
  191.                 /* don't care */
  192.                 break;
  193.             case app4Evt:
  194.                 switch ((gERecord.message >> 24) & 0x0FF) {     /* high byte of message */
  195.                     case suspendResumeMessage:              /* suspend/resume is also an activate/deactivate */
  196.                         gInBackground = (gERecord.message & kResumeMask) == 0;
  197.                         break;
  198.                 }
  199.                 break;
  200.             default:
  201.                 break;
  202.                 /* This dispatches high level events (AppleEvents, for example) */
  203.                 /* to our dispatch routine.  This is NEW in the event loop for */
  204.                 /* System 7 */
  205.             case kHighLevelEvent:
  206.                 DoHighLevel(&gERecord);
  207.                 break;
  208.                 
  209.         }
  210.     } while (gQuit != true);
  211.     
  212.     
  213. }
  214.  
  215. /* DoDaCall opens the requested DA.  It's here as a seperate routine if you'd */
  216. /* like to perform some action or just know when a DA is opened in your */
  217. /* layer.  Can be handy to track memory problems when a DA is opened */
  218. /* with an Option-open */
  219. void DoDaCall(MenuHandle themenu, long theit)
  220. {
  221.     long qq;
  222.     Str255 DAname;
  223.     GetMenuItemText(themenu, theit, DAname);
  224.     qq = OpenDeskAcc(DAname);
  225. }
  226.  
  227. /* end DoDaCall */
  228.  
  229. /* DoDiskEvents just checks the error code from the disk mount, */
  230. /* and puts up the 'Format' dialog (through DIBadMount) if need be */
  231. /* You can do much more here if you care about what disks are */
  232. /* in the drive */
  233. void DoDiskEvents(long dinfo)                               /* hi word is error code, lo word is drive number */
  234. {
  235.     short hival, loval, tommy;
  236.     Point fredpoint =  {
  237.         40, 40
  238.     };
  239.     hival = HiWord(dinfo);
  240.     loval = LoWord(dinfo);
  241.     if (hival != noErr)                                     /* something happened */ {
  242.         tommy = DIBadMount(fredpoint, dinfo);
  243.     }
  244. }
  245.  
  246. void DrawMain(WindowPtr drawIt)
  247. {
  248.     BeginUpdate(drawIt);
  249.     SetPort(drawIt);
  250.     MoveTo(40, 70);
  251.     TextFace(bold);
  252.     TextSize(20);
  253.     DrawString("\pThis Does Nothing");
  254.     EndUpdate(drawIt);
  255. }
  256.  
  257. Boolean DoSelected(long val)
  258. {
  259.     short loval, hival;
  260.     Boolean temp = false;
  261.     loval = LoWord(val);
  262.     hival = HiWord(val);
  263.     
  264.     switch (hival) {                                        /* switch off the menu number selected */
  265.         case kAppleMenu:                                    /* Apple menu */
  266.             if (loval != 1) {                               /* if this was not About, it's a DA */
  267.                 DoDaCall(gAppleMenuHandle, loval);
  268.             } else {
  269.                 Alert(128, nil);                            /* do about box */
  270.             }
  271.             break;
  272.         case kFileMenu:                                     /* File menu */
  273.             gQuit = true;                                   /* only edit item */
  274.             break;
  275.         case kEditMenu:
  276.             /* edit menu junk */
  277.             /* don't care */
  278.             break;
  279.         case kToolsMenu:
  280.             if (loval != gInteractNow) {
  281.                 CheckItem(gToolMenuHandle, gInteractNow, false);
  282.                 CheckItem(gToolMenuHandle, loval, true);
  283.                 AESetInteractionAllowed(gInteractArray[loval]);
  284.                 gInteractNow = loval;
  285.             }
  286.     }
  287.     HiliteMenu(0);
  288.     return temp;
  289. }
  290.  
  291. void InitAEStuff(void)
  292. {
  293.     OSErr aevtErr = noErr;
  294.     long aLong = 0;
  295.     Boolean gHasAppleEvents = false;
  296.     /* Check this machine for AppleEvents.  If they are not here (ie not 7.0)
  297.     *   then we exit */
  298.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
  299.     /* The following series of calls installs all our AppleEvent Handlers.
  300.     *   These handlers are added to the application event handler list that 
  301.     *   the AppleEvent manager maintains.  So, whenever an AppleEvent happens
  302.     *   and we call AEProcessEvent, the AppleEvent manager will check our
  303.     *   list of handlers and dispatch to it if there is one.
  304.     */
  305.     if (gHasAppleEvents) {
  306.             aevtErr =  AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, 
  307.                         NewAEEventHandlerProc(AEOpenHandler),0, false);
  308.                         if (aevtErr)  ExitToShell();
  309.  
  310.             aevtErr =  AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, 
  311.                         NewAEEventHandlerProc(AEOpenDocHandler),0, false);
  312.                         if (aevtErr)  ExitToShell();
  313.             
  314.             aevtErr = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, 
  315.                         NewAEEventHandlerProc(AEPrintHandler),0, false);
  316.                         if (aevtErr)  ExitToShell();
  317.            
  318.             aevtErr = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, 
  319.                         NewAEEventHandlerProc(AEQuitHandler),0, false);
  320.                         if (aevtErr)  ExitToShell();
  321.            
  322.             aevtErr = AEInstallEventHandler(kSimpleClass, kSimpleEvent, 
  323.                         NewAEEventHandlerProc(AESimpleHandler),0, false);
  324.                         if (aevtErr)  ExitToShell();
  325.                                 
  326.             /* create a UPP for the AppleEvent idle proc */
  327.             gAEIdleUPP = NewAEIdleProc(idleProc);
  328.  
  329.             }
  330.   else ExitToShell();
  331. }
  332.  
  333. /* end InitAEStuff */
  334.  
  335. void DoHighLevel(EventRecord *AERecord)
  336. {
  337.     
  338.     AEProcessAppleEvent(AERecord);
  339.     
  340. }
  341.  
  342. /* end DoHighLevel */
  343.  
  344. /* This is the standard Open Application event.  You'll get this as one of the (if not the ) */
  345. /* first events in your application.  So, we open up a blank document */
  346.      OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  347. {
  348. #pragma unused (messagein,reply,refIn)
  349.     /* we of course don't do anything here, since we're background only */
  350.     return(noErr);
  351. }
  352.  
  353. /* end AEOpenHandler */
  354.  
  355. /* Open Doc, opens our documents.  Remember, this can happen at application start AND */
  356. /* anytime else.  If your app is up and running and the user goes to the desktop, hilites one */
  357. /* of your files, and double-clicks or selects Open from the finder File menu this event */
  358. /* handler will get called. Which means you don't do any initialization of globals here, or */
  359. /* anything else except open then doc.  */
  360. /* SO-- Do NOT assume that you are at app start time in this */
  361. /* routine, or bad things will surely happen to you. */
  362.  
  363. OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  364. {
  365. #pragma unused (messagein,reply, refIn)
  366.     /* we of course don't do anything here */
  367.     return(errAEEventNotHandled);                           /* we have no docs, so no odoc events should come to us */
  368.     
  369. }
  370. OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  371. {                                                           /* no printing handler in yet, so we'll ignore this */
  372.     /* the operation is functionally identical to the ODOC event, with the additon */
  373.     /* of calling your print routine.  */
  374. #pragma unused (messagein,reply,refIn)
  375.     /* we of course don't do anything here */
  376.     return(errAEEventNotHandled);                           /* we have no docs, so no odoc events should come to us */
  377. }
  378.  
  379. /* Standard Quit event handler, to handle a Quit event from the Finder, for example.  */
  380. /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life.  */
  381.      OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  382. {
  383. #pragma unused (messagein,refIn,reply)
  384.     
  385.     /* prepQuit sets the Stop flag for us.  It does _NOT_ quit, you */
  386.     /* should NEVER quit from an AppleEvent handler.  Calling */
  387.     /* ExitToShell here would blow things up */
  388.     gQuit = true;
  389.     return(noErr);
  390. }
  391.  
  392. OSErr AESimpleHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  393. {
  394.     #pragma unused(messagein,reply,refIn)
  395.     OSErr myErr = AEInteractWithUser(kAEDefaultTimeout, nil, gAEIdleUPP);
  396.     if (myErr != errAENoUserInteraction)
  397.         Alert(444, nil);
  398.     return(noErr);
  399. }
  400.  
  401. pascal Boolean idleProc(EventRecord *eventIn, long *sleep, RgnHandle *mouseRgn)
  402. {
  403.     switch (eventIn->what) {
  404.         case nullEvent:
  405.             /* no nul processing in this sample */
  406.             *sleep = 0;
  407.             mouseRgn = nil;
  408.             break;
  409.         case updateEvt:
  410.         case activateEvt:
  411.             DrawMain((WindowPtr)eventIn->message);          /* draw whatever window needs an update */
  412.             break;
  413.         case app4Evt:
  414.             switch ((gERecord.message >> 24) & 0x0FF) {     /* high byte of message */
  415.                 case suspendResumeMessage:                  /* suspend/resume is also an activate/deactivate */
  416.                     gInBackground = (gERecord.message & kResumeMask) == 0;
  417.                     break;
  418.             }
  419.             break;
  420.             
  421.             
  422.     }
  423.     return(false);                                          /* I'll wait forever */
  424. }
  425.